package com.zzzy.doc.controller.mydoc;


import com.zhuozhengsoft.pageoffice.DocumentOpenType;
import com.zhuozhengsoft.pageoffice.FileMakerCtrl;
import com.zhuozhengsoft.pageoffice.FileSaver;
import com.zhuozhengsoft.pageoffice.OpenModeType;
import com.zhuozhengsoft.pageoffice.word.DataRegionInsertType;
import com.zhuozhengsoft.pageoffice.word.DataRegionWriter;
import com.zhuozhengsoft.pageoffice.word.WordDocumentWriter;
import com.zzzy.common.enums.YesOrNoEnum;
import com.zzzy.common.util.FileUtil;
import com.zzzy.common.vo.AjaxResult;
import com.zzzy.common.vo.PageResult;
import com.zzzy.doc.common.util.InitDataPageOfficeUtil;
import com.zzzy.doc.dao.entity.DocRedSheetTemplate;
import com.zzzy.doc.dto.DataRegionDto;
import com.zzzy.doc.service.DocRedSheetTemplateService;
import com.zzzy.doc.service.mydoc.MyDocRedSheetService;
import com.zzzy.doc.vo.document.DocBasicInfoRes;
import com.zzzy.doc.vo.document.DocInfoRes;
import com.zzzy.doc.vo.pageoffice.OpenOfficeFileRes;
import com.zzzy.doc.vo.template.DocTemplateForSelectPageReq;
import com.zzzy.framework.common.annotation.RepeatSubmit;
import com.zzzy.framework.common.util.PageOfficeUtil;
import com.zzzy.framework.common.util.ReflectionUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

@Tag(name = "我的公文-清稿套红", description = "doc114")
@Validated
@RestController
@RequestMapping("/doc/my")
public class MyDocRedSheetController {

    @Resource
    private MyDocRedSheetService myDocRedSheetService;
    @Resource
    private DocRedSheetTemplateService docRedSheetTemplateService;

    @GetMapping(value = "/redSheetTemplate/page")
    @Operation(summary = "选择公文套红模板分页列表")
    @PreAuthorize("@pvs.hasPermission('doc:my:page')")
    public AjaxResult<PageResult<DocRedSheetTemplate>> page(@Valid @ParameterObject DocTemplateForSelectPageReq queryReq) {
        PageResult<DocRedSheetTemplate> redSheetTemplatePage = docRedSheetTemplateService.getPageForSelect(queryReq);
        return AjaxResult.success(redSheetTemplatePage);
    }

    @RepeatSubmit
    @PostMapping("/redSheetAutoFill")
    @Operation(summary = "清稿套红模板自动填充")
    @Parameter(name = "id", description = "公文ID", required = true)
    @Parameter(name = "templateId", description = "清稿套红模板ID", required = true)
    @PreAuthorize("@pvs.hasPermission('doc:my:update')")
    public AjaxResult<OpenOfficeFileRes> redSheetAutoFill(@NotNull(message = "公文ID不能为空") Long id, @NotNull(message = "套红模板ID不能为空") Long templateId) {
        DocBasicInfoRes docBasicInfo = myDocRedSheetService.getDocBasicInfo(id);
        DocRedSheetTemplate redSheetTemplate = docRedSheetTemplateService.getTemplateByIdForQuery(templateId);
        String openTemplateFileUrl = "/doc/my/getRedSheetTemplateFileStream/" + templateId;
        //数据标签自动填充
        WordDocumentWriter doc = new WordDocumentWriter();
        for (DataRegionDto dataRegionDto : redSheetTemplate.getDataRegions()) {
            DataRegionWriter dataRegionWriter = doc.openDataRegion(dataRegionDto.getName());
            Object fieldValue = ReflectionUtil.getFieldValue(docBasicInfo, dataRegionDto.getName());
            if ("printDate".equals(dataRegionDto.getName())){
                fieldValue = Objects.nonNull(docBasicInfo.getPrintDate()) ? docBasicInfo.getPrintDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")) : "";
            }
            String value = Objects.isNull(fieldValue) ? "" : String.valueOf(fieldValue);
            dataRegionWriter.setValue(value);
        }
        DataRegionDto redSheetDataRegion = InitDataPageOfficeUtil.getMainDataRegion();
        DataRegionWriter dataRegion = doc.openDataRegion(redSheetDataRegion.getName());
        String openMainFileUrl = "/doc/my/getMainDocFileStream/" + id;
        dataRegion.setValue("[word]"+ openMainFileUrl +"[/word]");

        String wordHtml = PageOfficeUtil.getWordHtml(openTemplateFileUrl, docBasicInfo.getSubject(), OpenModeType.docAdmin,doc);
        OpenOfficeFileRes openOfficeFileRes = OpenOfficeFileRes.builder().html(wordHtml).edit(true).build();
        return AjaxResult.success(openOfficeFileRes);
    }

    @GetMapping(value = "/getRedSheetTemplateFileStream/{templateId}")
    @Operation(summary = "获取套红模板文件流")
    @Parameter(name = "templateId", description = "套红模板ID", required = true)
    @PreAuthorize("@pvs.hasPermission('doc:my:page')")
    public void getRedSheetTemplateFileStream(@NotNull(message = "套红模板ID不能为空") @PathVariable("templateId") Long templateId, HttpServletResponse response) {
        DocRedSheetTemplate redSheetTemplate = docRedSheetTemplateService.getTemplateByIdForQuery(templateId);
        byte[] fileBlob = redSheetTemplate.getFileBlob();
        FileUtil.outputFileStream(response, fileBlob, redSheetTemplate.getName() + "." + FileUtil.DOCX);
    }

    @GetMapping(value = "/getRedSheetPageOfficeFile/{id}")
    @Operation(summary = "打开套红后文件")
    @Parameter(name = "id", description = "公文ID", required = true)
    @PreAuthorize("@pvs.hasPermission('doc:my:page')")
    public AjaxResult<OpenOfficeFileRes> getRedSheetPageOfficeFile(@NotNull(message = "公文ID不能为空") @PathVariable("id") Long id) {
        String openFileUrl = "/doc/my/getRedSheetPageOfficeFileStream/" + id;
        String wordHtml = PageOfficeUtil.getWordHtml(openFileUrl, myDocRedSheetService.getDocById(id).getSubject(), OpenModeType.docAdmin);
        OpenOfficeFileRes openOfficeFileRes = OpenOfficeFileRes.builder().html(wordHtml).edit(true).build();
        return AjaxResult.success(openOfficeFileRes);
    }

    @GetMapping(value = "/getRedSheetPageOfficeFileStream/{id}")
    @Operation(summary = "获取套红模板文件流")
    @PreAuthorize("@pvs.hasPermission('doc:my:page')")
    public void getRedSheetPageOfficeFileStream(@NotNull(message = "公文ID不能为空") @PathVariable("id") Long id, HttpServletResponse response) {
        DocInfoRes docInfo = myDocRedSheetService.getDocInfo(id);
        byte[] fileBlob = Objects.nonNull(docInfo.getRedSheetFileBlob()) ? docInfo.getRedSheetFileBlob() : docInfo.getMainFileBlob();
        FileUtil.outputFileStream(response, fileBlob, docInfo.getSubject() + "." + FileUtil.DOCX);
    }

    @PostMapping(value = "/updateRedSheetFile/{id}")
    @Operation(summary = "保存套红后文件")
    @Parameter(name = "id", description = "公文ID", required = true)
    @PreAuthorize("@pvs.hasPermission('doc:my:update')")
    public void updateRedSheetFile(@NotNull(message = "公文ID不能为空") @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) {
        FileSaver fs = new FileSaver(request, response);
        myDocRedSheetService.updateRedSheetFile(id, fs.getFileBytes());
        fs.setCustomSaveResult("ok");
        fs.close();
    }

    @PostMapping("/mergeAndToPdf/{id}")
    @Operation(summary = "呈批表与正文合并并转换为PDF")
    @Parameter(name = "id", description = "公文ID", required = true)
    @PreAuthorize("@pvs.hasPermission('doc:my:update')")
    public void mergeApprovalAndMain(@NotNull(message = "公文ID不能为空") @PathVariable("id") Long id
            , HttpServletRequest request, HttpServletResponse response) throws IOException {
        DocInfoRes docInfo = myDocRedSheetService.getDocInfo(id);
        FileMakerCtrl fmCtrl = new FileMakerCtrl(request);
        WordDocumentWriter doc = new WordDocumentWriter();
        //已呈批表为原文件，在呈批表后插入分页符（需先添加数据区域定位），再插入正文（需添加数据区域定位）
        String openApprovalFileUrl = "/doc/my/getApprovalDocFileStream/" + id;
        DataRegionWriter pageBreakDataRegion = doc.createDataRegion("PageBreak", DataRegionInsertType.After, "[end]");
        pageBreakDataRegion.selectEnd();
        //插入分页符
        doc.insertPageBreak();

        DataRegionWriter approvalDataRegion = doc.createDataRegion(InitDataPageOfficeUtil.getMainDataRegion().getName(), DataRegionInsertType.After, "[end]");
        String openMainFileUrl = "/doc/my/getRedSheetPageOfficeFileStream/" + id;
        approvalDataRegion.setValue("[word]"+ openMainFileUrl +"[/word]");
        if (YesOrNoEnum.YES.getValue().equals(docInfo.getIsWaterMark())) {
            doc.getWaterMark().setText(docInfo.getSecretLevel());
            fmCtrl.setWriter(doc);
        }
        fmCtrl.setWriter(doc);
        fmCtrl.fillDocumentAsPDF(openApprovalFileUrl, DocumentOpenType.Word, docInfo.getSubject()+ "." + FileUtil.PDF);
        response.getOutputStream().print(fmCtrl.getHtml());
    }

    @PostMapping(value = "/redSheetCompleteWithSavePdf/{id}")
    @Operation(summary = "套红完毕并保存pdf")
    @Parameter(name = "id", description = "合同ID", required = true)
    @PreAuthorize("@pvs.hasPermission('con:my:update')")
    public void redSheetCompleteWithSavePdf(@NotNull(message = "合同ID不能为空") @PathVariable("id") Long id,
                                 HttpServletRequest request, HttpServletResponse response) {
        FileSaver fs = new FileSaver(request, response);
        myDocRedSheetService.redSheetCompleteWithSavePdf(id, fs.getFileBytes());
        fs.setCustomSaveResult("ok");
        fs.close();
    }

}
